package com.cskaoyan.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.List;

@Aspect
@Component
public class MapperExampleAspect {


    // 自动加上deleted = 0
    // select / count byExample
    @Before("execution(* com..mapper..*Example(..))") //pointcut=“切入点表达式”
    public void before(JoinPoint joinPoint) {

        Signature signature = joinPoint.getSignature();//方法的描述
        String name = signature.getName(); //方法名
        if (name.startsWith("count") || name.startsWith("select")) {

            Object[] args = joinPoint.getArgs(); //携带的参数

            for (Object arg : args) {
                Class<?> exampleClass = arg.getClass();
                if (exampleClass.getSimpleName().endsWith("Example")) {

                    //  调用 List<Criteria> getOredCriteria获取第一个Criteria
                    // 遍历其中的 criteria List<Criterion>
                    //    判断是否有condition等于"deleted ="的值
                    //    若没有则加上一个 调用 criteria.andDeletedEqualTo(false) 方法

                    try {
                        Method getOredCriteria = exampleClass.getDeclaredMethod("getOredCriteria");

                        List<?> oredCriteria = (List<?>) getOredCriteria.invoke(arg);
                        Object criteria;
                        boolean findDeleted = false;

                        if (oredCriteria.size() > 0) {
                            criteria = oredCriteria.get(0);
                            List<?> criterionList = (List<?>) criteria.getClass().getDeclaredMethod("getAllCriteria").invoke(criteria);


                            for (Object criterion : criterionList) {
                                String condition = (String) criterion.getClass().getDeclaredMethod("getCondition").invoke(criterion);
                                if (condition.equals("deleted =")) {
                                    findDeleted = true;
                                    break;
                                }
                            }
                        }else {
                            criteria = exampleClass.getDeclaredMethod("createCriteria").invoke(arg);
                        }

                        if (!findDeleted) {
                            criteria.getClass()
                                    .getDeclaredMethod("andDeletedEqualTo" , Boolean.class)
                                    .invoke(criteria, false);
/*
                            System.out.println(String.format("add deleted=0 for %s(%s)",
                                    name, arg.getClass().getSimpleName()));*/
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                }
            }
        }

    }


}
